(function(layui) {
  'use strict';

  /**
   * @typedef {ArrayLike} jQuery
   */

  var MODULE_NAME = 'renderTemplate';

  function _f(input) {
    var data;
    try {
      data = new Function('return ' + input)();
    } catch (e) {
      data = input;
    }
    return data;
  }

  function _camel(input) {
    var c = function(all, letter) {
      return letter.toUpperCase();
    };
    return typeof input === 'string' ? input.replace(/-([a-z])/ig, c) : input;
  }

  layui.extend({
    'ResizeDetector': './lib/resize-detector'
  }).define(['jquery', 'form', 'ResizeDetector'], function(exports) {
    var $ = layui.jquery;
    var form = layui.form;
    var ResizeDetector = layui.ResizeDetector;

    exports(MODULE_NAME, {
      tableSearch: renderTableSearch
    });

    /**
     * 渲染表格查询区域
     * @param {Object} options
     * @param {string|HTMLElement|jQuery} options.el 挂载的 dom 对象
     * @param {string} options.searchText 查询按钮的文字，默认是 查询，可在全局配置LAYUI_GLOBAL的tableSearch下配置
     * @param {string} options.resetText 重置按钮的文字，默认是 重置，可在全局配置LAYUI_GLOBAL的tableSearch下配置
     * @param {boolean} options.reverse 是否将按钮反向排版，默认重置在左，查询在右，可在全局配置LAYUI_GLOBAL的tableSearch下配置
     * @param {Function} options.success 渲染成功的回调
     * @param {Function} options.search 查询按钮的回调
     * @param {Function} options.reset 重置按钮的回调
     */
    function renderTableSearch(options) {
      /**
       * 获取全局配置，默认只提取以下属性
       * - searchText
       * - resetText
       * - reverse
       */
      var LayuiGlobalOptions = (window.LAYUI_GLOBAL || {}).tableSearch || {};
      var globalSearchText = LayuiGlobalOptions.searchText || '查询';
      var globalResetText = LayuiGlobalOptions.resetText || '重置';
      var globalReverse = LayuiGlobalOptions.reverse || false;
      /**
       * 默认配置
       * @type {typeof options}
       */
      var defaultOptions = {
        el        : null,
        searchText: globalSearchText,
        resetText : globalResetText,
        reverse   : globalReverse,
        // callback
        success   : null,
        search    : null,
        reset     : null
      };
      // lay-form-item 上可用的合法属性
      var itemValidAttributes = 'label,html-for,size,tooltip';
      // 合并配置
      var mergedOptions = $.extend({}, defaultOptions, options);
      // 只匹配第一符合的 dom
      var $template = $(mergedOptions.el).eq(0);
      // 如果找到符合项隐藏它，反之结束渲染
      if ($template.length) $template.addClass('layui-hide');
      else return;

      var domTemplate = $template[0];
      // 判断是不是 template 标签，这个需要特殊处理
      var isTemplateElement = domTemplate.tagName === 'TEMPLATE' && domTemplate.nodeType === 1;
      var $target = isTemplateElement
        ? $(domTemplate.content.querySelector('lay-form-table-search'))
        : $($template.html()).eq(0); // 考虑到有的使用了 script 标签

      var html = '';
      // 模版内没有提供对应代码则结束渲染
      if (!$target.length) return;
      // 渲染代码（这里可以适当的调整自己需要的）
      html += [
        '<div class="layui-card"><div class="layui-card-body" style="padding-bottom: 0;"><form class="layui-form"><div class="layui-row">',
        renderItems($target),
        renderActions(mergedOptions),
        '</div></form></div></div>'
      ].join('');
      // 将渲染好的代码添加模板之后
      $template.after(html);
      // 渲染表单中的选择框
      form.render('select');
      // 找到渲染后的模板对象
      var $rendered = $template.next();

      ResizeDetector.addResizeListener($rendered[0], function() {
        var $form = $rendered.find('.layui-form');
        var width = $form.width();
        var html = [
          '<div class="layui-row">',
          renderItems($target, width),
          renderActions(mergedOptions, width),
          '</div>'
        ].join('');
        $form.html(html);
        form.render('select');
        captureHooks(mergedOptions, $rendered);
      });
      // 调用钩子
      captureHooks(mergedOptions, $rendered);

      function captureHooks(options, $scope) {
        // 调用成功钩子
        $.isFunction(options.success) && options.success($scope);
        // 如果存在 search 或 reset 方法，则渲染的按钮自动绑定事件
        if (
          $.isFunction(options.search) ||
          $.isFunction(options.reset)
        ) {
          $rendered.find('button[data-action]').on('click', function() {
            var $this = $(this);
            var action = $this.data('action');
            action === 'search' && $.isFunction(options.search) && options.search.call(this, $scope);
            action === 'reset' && $.isFunction(options.reset) && options.reset.call(this, $scope);
          });
        }
      }

      /**
       * 根据 lay-form-item 的位置返回对应的类名
       * @param {number} size lay-form-item 占用的位置
       *
       * 一个 lay-form-item 临界值使用 110 + 220
       */
      function renderItemClass(size, width) {
        if (width) {
          if (width >= 330 * 4) {
            return 'layui-col-xs3';
          } else if (width >= 330 * 3) {
            return 'layui-col-xs4';
          } else if (width >= 330 * 2) {
            return 'layui-col-xs6';
          } else {
            return 'layui-col-xs12';
          }
        }
        switch (size) {
          case 0:
            return 'layui-hide';
          case 2:
            return 'layui-col-xs12 layui-col-sm12 layui-col-md8 layui-col-lg6';
          case 3:
            return 'layui-col-xs12 layui-col-sm12 layui-col-md12 layui-col-lg9';
          case 4:
            return 'layui-col-xs12 layui-col-sm12 layui-col-md12 layui-col-lg12';
          default:
            return 'layui-col-xs12 layui-col-sm6 layui-col-md4 layui-col-lg3';
        }
      }
      /**
       * 渲染 lay-form-item
       * @param {jQuery} $target
       */
      function renderItems($target, width) {
        var $items = $target.find('lay-form-item');
        var html = '';

        $items.each(function(i, item) {
          var $item = $(item);
          var raw = {};
          itemValidAttributes.split(',').forEach(function(attr) {
            raw[_camel(attr)] = _f($item.attr(attr));
          });

          // 完善 input 框属性
          var $inputs = $item.find('input');
          $inputs.each(function(i, input) {
            var $input = $(input);
            var type = $input.attr('type');
            if (!type) {
              $input.attr('type', 'text');
            }
            if (raw.htmlFor !== false) {
              $input.attr('id', raw.htmlFor);
            }
            $input.addClass('layui-input');
          });

          html += [
            '<div class="' + renderItemClass(raw.size, width) + '">',
            '  <div class="layui-form-item">',
            '    <label' + (raw.tooltip ? ' layadmin-tip="' + raw.tooltip + '"' : '') + ' class="layui-form-label">' + raw.label + '</label>',
            '    <div class="layui-input-block">' + $item.html() + '</div>',
            '  </div>',
            '</div>'
          ].join('');
        });

        return html;
      }

      function renderActions(options, width) {
        var html = '';
        var searchFn = options.search;
        var resetFn = options.reset;
        var searchText = 'searchText' in options ? options.searchText : globalSearchText;
        var resetText = 'resetText' in options ? options.resetText : globalResetText;
        var reverse = 'reverse' in options ? options.reverse : globalReverse;

        if (!searchFn && !resetFn) return html;

        html += '<div class="' + renderItemClass(1, width) + '"><div class="layui-form-item"><div class="layui-input-block">';
        // 调整代码已适配项目需要的按钮
        var text = [];
        // 重置按钮采用原始样式
        text.push('<button class="layui-btn layui-btn-primary" type="button" data-action="reset">' + resetText + '</button>');
        // 查询按钮采用默认样式
        text.push('<button class="layui-btn" type="button" data-action="search">' + searchText + '</button>');
        // 是否需要反转按钮，LTR 文档下：重置在左，查询在右
        html += reverse ? text.reverse().join('') : text.join('');
        html += '</div></div></div>';

        return html;
      }
    }
  });
})(layui);
